/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
							   adventure_map_window.h

	$Header: /game/adventure_map_window.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef ADVENTURE_MAP_WINDOW_H_INCLUDED
#define ADVENTURE_MAP_WINDOW_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "adventure_map_ptr.h"
#include "adventure_map_window_ptr.h"
#include "adventure_map_window_base.h"
#include "adventure_spell_targeter_ptr.h"
#include "animation_ptr.h"
#include "army_ptr.h"
#include "bitmap_cursor.h"
#include "bitmap_group_ptr.h"
#include "bitmap_group_window_ptr.h"
#include "game_window.h"
#include "idle_processor.h"
#include "map_renderer.h"
#include "mouse_window_ptr.h"
#include "paint_surface.h"
#include "memory_bitmap.h"

class  t_adventure_frame;
class  t_adventure_object;
struct t_adventure_path_data;
struct t_adventure_path_point;
class  t_army_mover;
struct t_adv_map_point;

// ------------------------------------------------------------------------
// window to display an adventure map
// ------------------------------------------------------------------------
class t_adventure_map_window : public t_adventure_map_window_base
{
public:
	typedef t_adventure_spell_targeter		t_spell_targeter;
	typedef t_adventure_spell_targeter_ptr	t_spell_targeter_ptr;

	t_adventure_map_window( t_screen_rect const& rect, t_adventure_frame* parent );
	virtual ~t_adventure_map_window();

	t_object_id				adv_object_hit_test( t_screen_point const & point ) const;
	void					check_enemy_attack( t_army* army, t_handler enemy_attack_started_handler = t_handler() );
	void					clear_enemy_attack();
	void					clear_spell_targeter();
	bool					enemy_is_moving() const;
	t_bitmap_cursor const&	get_attack_cursor() const;
	t_army* 				get_attacking_army() const;
	virtual std::string 	get_help_text( t_screen_point point ) const;
	t_bitmap_cursor const&	get_activate_cursor() const;
	t_bitmap_cursor const&	get_move_cursor() const;
	t_bitmap_cursor const&	get_normal_cursor() const;
	t_adventure_object* 	get_object( t_screen_point point ) const;
	t_counted_ptr<t_army_mover> get_object_mover();
	t_bitmap_cursor const&	get_transfer_cursor() const;
	bool					halt_movement();
	bool					is_visible( t_screen_point const& point ) const;
	bool					is_visible( t_level_map_point_2d const& point ) const;
	virtual void			left_button_down( t_mouse_event const& event );
	virtual void			left_button_up( t_mouse_event const& event );
	virtual void			left_double_click( t_mouse_event const& event );
	void					move_enemy_army( t_army* army, t_adv_map_point const& point );
	virtual void			mouse_move( t_mouse_event const& event );
	virtual void			on_close();
	virtual void			on_size_change( t_screen_rect const& rect ); // in client coordinates of parent
	virtual void			paint( t_paint_surface& paint_surface );
	virtual void			right_button_up( t_mouse_event const& event );
	void					run_object_mover( t_counted_ptr<t_army_mover>	object_mover,
											  bool							allow_cancel );
	void					set_frame( t_adventure_frame* parent );
	void					set_spell_targeter( t_spell_targeter_ptr new_targeter );
	void					update_cursor();
	bool					use_boat_cursors() const;
	
protected:

	// Member functions
	virtual t_abstract_bitmap16_ptr create_back_buffer( t_screen_point const & view_size );

	void					drag( t_screen_point point );
	bool					get_bridge_point( t_screen_point const& screen_point,
											  t_adv_map_point& map_point ) const;
	t_bitmap_cursor const&	get_move_cursor( t_adventure_path_point const& point ) const;
	t_mouse_window* 		get_new_cursor( t_screen_point point ) const;
	bool					get_path_point( t_adv_map_point const& map_point,
											t_adventure_path_point& path_point ) const;
	bool					get_path_point( t_screen_point const& screen_point,
											t_adventure_path_point& path_point ) const;
	bool					hidden_by_fog_of_war( t_adventure_object const & object ) const;
	virtual void			on_rects_dirtied( std::vector< t_screen_rect > const & dirtied_rects );
	virtual void			on_view_moved( int new_view_level, t_screen_point const & new_view_pos, 
										t_screen_point const & new_view_size );
	void					update_cursor( t_screen_point point );

	t_bitmap_cursor					m_activate_cursor;
	t_bitmap_cursor					m_activate_boat_cursor;
	t_bitmap_cursor					m_anchor_cursor;
	t_bitmap_cursor					m_attack_cursor;
	t_army_ptr						m_attacking_enemy;
	t_shared_ptr<t_memory_bitmap16>	m_back_buffer;
	bool							m_dragging;
	t_screen_point					m_drag_start;
	t_counted_ptr<t_army_mover> 	m_object_mover;
	t_bitmap_cursor					m_normal_cursor;
	t_bitmap_cursor					m_move_cursor;
	t_bitmap_cursor					m_move_boat_cursor;
	t_mouse_window_ptr				m_spell_cursor;
	t_animation_ptr					m_spell_cursor_animation;
	t_spell_targeter_ptr			m_spell_targeter;
	t_bitmap_cursor					m_transfer_cursor;
};



inline bool t_adventure_map_window::enemy_is_moving() const
{
	return m_attacking_enemy != 0;
}


inline t_bitmap_cursor const& t_adventure_map_window::get_activate_cursor() const
{
	if (use_boat_cursors())
		return m_activate_boat_cursor;
	return m_activate_cursor;
}

inline t_bitmap_cursor const& t_adventure_map_window::get_attack_cursor() const
{
	return m_attack_cursor;
}

inline t_bitmap_cursor const& t_adventure_map_window::get_normal_cursor() const
{
	return m_normal_cursor;
}

inline t_bitmap_cursor const& t_adventure_map_window::get_move_cursor() const
{
	if (use_boat_cursors())
		return m_move_boat_cursor;
	return m_move_cursor;
}

inline t_counted_ptr<t_army_mover> t_adventure_map_window::get_object_mover()
{
	return m_object_mover;
}

inline t_bitmap_cursor const& t_adventure_map_window::get_transfer_cursor() const
{
	return m_transfer_cursor;
}

inline void t_adventure_map_window::set_frame( t_adventure_frame* parent )
{
	m_frame = parent;
}

#endif
